{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "f11e8907-c7cb-40d4-87fe-d4ee5f6912ca",
   "metadata": {},
   "outputs": [],
   "source": [
    "from pyspark.sql import SparkSession\n",
    "\n",
    "sc = SparkSession.builder \\\n",
    "    .appName(\"lesson4\") \\\n",
    "    .config(\"spark.driver.memory\", \"4g\") \\\n",
    "    .config(\"spark.executor.memory\", \"2g\") \\\n",
    "    .getOrCreate()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "096a6800-d9f0-4312-84d7-753decde75a7",
   "metadata": {},
   "source": [
    "## 使用spark sql 探索数据\n",
    "为了限制机动车保有量，从 2011 年开始，北京市政府推出了小汽车摇号政策。随着摇号进程的推进，在 2016 年，为了照顾那些长时间没有摇中号码牌的“准司机”，摇号政策又推出了“倍率”制度。\n",
    "\n",
    "所谓倍率制度，它指的是，结合参与摇号次数，为每个人赋予不同的倍率系数。有了倍率加持，大家的中签率就由原来整齐划一的基础概率，变为“基础概率 * 倍率系数”。参与摇号的次数越多，倍率系数越大，中签率也会相应得到提高\n",
    "\n",
    "这里使用spark-sql 探索倍率与中签率之间的关系,你可以通过 [这个地址](https://pan.baidu.com/s/1Vys1Z1mofQFoU52ye7SKuw)，从网盘进行下载，提取码为ajs6\n",
    "\n",
    "![17484357951021748435794154.png](https://gitee.com/y19941115mx/picture-bed/raw/master/17484357951021748435794154.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bdd044c8-9d5b-4cf4-bdbd-0a6b2f750ef1",
   "metadata": {},
   "source": [
    "### 1. 数据探索"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "db2015ad-6fda-4790-8d82-090ccd1457b0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "root\n",
      " |-- carNum: string (nullable = true)\n",
      " |-- batchNum: integer (nullable = true)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "from pathlib import Path\n",
    "\n",
    "file_path = Path('../') / 'data' / 'carData'\n",
    "\n",
    "apply_path = file_path / 'apply'\n",
    "\n",
    "apply_df = sc.read.parquet(str(apply_path.absolute()))\n",
    "\n",
    "apply_df.printSchema()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "77612a30-9a39-4daa-b044-a9288afbfdd5",
   "metadata": {},
   "outputs": [],
   "source": [
    "lucky_path = file_path / 'lucky'\n",
    "\n",
    "lucky_df = sc.read.parquet(str(lucky_path))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "6ed34bc3-b9ff-46fd-bfcb-7e4b0f8794c0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "45"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "apply_df.rdd.getNumPartitions()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "a26f4625-38d2-4609-9d75-ed7e1732f87c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lucky_df.rdd.getNumPartitions()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "39c5db45-6eb5-44ee-93eb-1fbe609680e9",
   "metadata": {},
   "source": [
    "### 2. 需求实现\n",
    "\n",
    "既然是要量化中签率与倍率之间的关系，我们只需要关注那些中签者（lucky 目录下的数据）的倍率变化就好了。而倍率的计算，要依赖 apply 目录下的摇号数据。因此，要做到仅关注中签者的倍率，我们就必须要使用数据关联这个在数据分析领域中最常见的操作。此外，由于倍率制度自 2016 年才开始推出，所以我们只需要访问 2016 年以后的数据即可\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ee5d0a0a-d9c9-4131-a04b-76548d9a67d1",
   "metadata": {},
   "outputs": [],
   "source": [
    "filter_lucky_df = lucky_df.filter(lucky_df.batchNum >= \"201601\").select(\"carNum\")\n",
    "join_df = filter_lucky_df.join(apply_df, \"carNum\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ae23855a-d498-4e7f-8f01-d66c050aeba2",
   "metadata": {},
   "source": [
    "倍率的计算，根据对数据的观察可以得出，根据每个批次和账号进行分词，出现的次数即为对应账号的抽取倍率"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5d8fa091-6ce7-4c1d-bbf4-186c183d22e8",
   "metadata": {},
   "outputs": [],
   "source": [
    "from pyspark.sql.functions import lit,count, max"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3c009185-ae5c-4255-9791-6ad40fe142b7",
   "metadata": {},
   "outputs": [],
   "source": [
    "multipliers = join_df.groupby([\"carNum\", \"batchNum\"]).agg(count(lit(1)).alias(\"multiplier\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "69188233-d5af-489f-a34b-6ac52ea5536d",
   "metadata": {},
   "source": [
    "最终倍率的计算，我们只需要按照每个账号批次的最大值即可"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "17ce12eb-1f69-4738-8df8-621ea061b3f7",
   "metadata": {},
   "outputs": [],
   "source": [
    "uniqueMultipliers = multipliers.groupby(\"carNum\").agg(max(\"multiplier\").alias(\"multiplier\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c5843a7f-761f-4156-b227-b1620a35ca33",
   "metadata": {},
   "source": [
    "按照multiplier分组 统计各个倍率下的中标人数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "ebf1c41b-f133-4fcd-9da8-b5f4b8658e75",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Object `count` not found.\n"
     ]
    }
   ],
   "source": [
    "result = uniqueMultipliers.groupby(\"multiplier\").count().sort(\"multiplier\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "bea961a2-21a8-4c96-b469-d3659cfa0337",
   "metadata": {},
   "outputs": [],
   "source": [
    "df = result.toPandas()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "2f0085f8-9da4-4192-b47a-4daad56cef9d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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OG3dmV7j5vz+5rOuAACAbRF0AAC4jBw/flxPPfWUrr76agUGBqpr166aOnWqpG/vlXfLLbcoKChIERERGjdunI4cOWI9NjU1VXl5eT77GzlypLKzs631K6+8UtOmTdM999yjkJAQde3aVS+88II1Hh8fL0n60Y9+JIfDodTU1At2rNJ53BkZAL6PCzGN3xan64FLxeTJk7VgwQLNnj1bN910kyorK/X555/r66+/1tChQ9W3b19t2bJF1dXV+uUvf6kHHnhACxcubNZzzJo1S7///e81ZcoU/fnPf9Z9992nn/zkJ7r22mu1efNm/cd//IfWrl2r6667rslnYrY0gg4AAJeJw4cP6/nnn9fcuXM1ZswYSdJVV12lm266SQsWLNDRo0f18ssvKzg4WJI0d+5cjRgxQk899dQZ71N3sv/8z//U+PHjJUkPP/ywZs+erXXr1unaa69V586dJUkRERFyuVwtfIRN8dYVAACXiW3btsnr9WrQoEGnHLv++uutkCNJ/fv31/Hjx7V9+/ZmPU/v3r2trx0Oh1wul/XZVRcbQQcAgMvEic+QOpUzfYzSie3t2rXTyRdrn/g4jO9q3759k8cfP368ue22CIIOAACXie7duysoKEjvvvtuk7GePXuqrKxMdXV11rYPPvhA7dq10zXXXCNJ6ty5s8+nEjQ2Nqq8vLxZPZw4J6exsfFcDqHZCDoAAFwmOnTooIcfflgPPfSQXn75Zf3jH/9QSUmJXnzxRf385z9Xhw4dNGbMGJWXl+v999/XhAkT5Ha7rfNzbrnlFq1cuVIrV67U559/rvHjx+vQoUPN6iEqKkpBQUEqKirSvn375PF4LsCR/hsnIwMA0IIu9asCf/e738nf31+PPvqo9u7dq5iYGP3qV79Sx44d9c477+jBBx/UjTfeqI4dO+r222/Xs88+az32nnvu0ccff6y7775b/v7++vWvf62BAwc26/n9/f31P//zP3riiSf06KOP6uabb9a6deta+Cj/jTsjc2dk4ILi8nLY0Znu2ouWwZ2RAQAAzoKgAwAAbIugAwAAbIugAwAAbIurroA2rKVP9OUkX6B5WusmeJeDlnptCToAADRTQECA2rVrp71796pz584KCAg47V2F0TzGGNXX12v//v1q167deX/oJ0EHAIBmateuneLj41VZWam9e/e2dju21LFjR3Xt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/Xq9XtXW1vosAADAvs456BhjNHHiRN10001KTEyUJFVVVUmSoqOjfWqjo6OtsaqqKgUEBCgsLOyMNVFRUU2eMyoqyqfm5OcJCwtTQECAVXOy6dOnW+f8OJ1OxcXFNfewAQBAG3LOQeeBBx7QJ598oldffbXJmMPh8Fk3xjTZdrKTa05Vfy413zV58mR5PB5rqaioOGNPAACgbTunoDNhwgS9+eabev/999WlSxdru8vlkqQmMyrV1dXW7IvL5VJ9fb1qamrOWLNv374mz7t//36fmpOfp6amRg0NDU1mek4IDAxUaGiozwIAAOyrWUHHGKMHHnhAf/nLX/Tee+8pPj7eZzw+Pl4ul0tr1qyxttXX12v9+vXq16+fJCkpKUnt27f3qamsrFR5eblVk5KSIo/Ho82bN1s1mzZtksfj8akpLy9XZWWlVbN69WoFBgYqKSmpOYcFAABsqllXXd1///165ZVX9MYbbygkJMSaUXE6nQoKCpLD4VBeXp6mTZum7t27q3v37po2bZo6duyorKwsq3bs2LGaNGmSIiIiFB4ervz8fPXq1cu6CqtHjx4aOnSocnJyNH/+fEnSuHHjlJGRoYSEBElSWlqaevbsKbfbrZkzZ+rgwYPKz89XTk4OMzUAAEBSM4POvHnzJEmpqak+21966SVlZ2dLkh566CEdPXpU48ePV01NjZKTk7V69WqFhIRY9bNnz5a/v79Gjx6to0ePatCgQVq4cKH8/PysmqVLlyo3N9e6OiszM1Nz5861xv38/LRy5UqNHz9e/fv3V1BQkLKysvTMM8806wUAALScK3+zssX3uWvG8BbfJy4fzQo6xpiz1jgcDhUUFKigoOC0NR06dNCcOXM0Z86c09aEh4dryZIlZ3yurl276q233jprTwAA4PLEZ10BAADbataMDi59LT1tzJQxAKAtY0YHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEHAADYFkEH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rZEjR/psi4uLU2VlpRITE895v/n5+Xr33XfPszsArY376ACwHT8/P7lcrvPaR6dOndSpU6fz2kdDQ4Pat29/XvsAcH6Y0QFwwaSmpmrChAnKy8tTWFiYoqOj9cILL6iurk7/9V//pZCQEF111VVatWqVpKZvH0nS66+/LofDccr9FxQUaNGiRXrjjTfkcDjkcDi0bt26Jm9drVu3Tg6HQytXrtT111+vDh06KDk5WVu3bj1t76d66+qll15Sjx491KFDB1177bX6wx/+YI2deM4//vGPSk1NVYcOHbRkyZLmv2gAWhRBB8AFtWjRIkVGRmrz5s2aMGGC7rvvPt1xxx3q16+f/v73vys9PV1ut1tff/11s/edn5+v0aNHa+jQoaqsrFRlZaX69et32vr//u//1jPPPKMtW7YoKipKmZmZamho+F7PtWDBAj3yyCOaOnWqtm3bpmnTpul3v/udFi1a5FP38MMPKzc3V9u2bVN6enqzjwlAyyLoALigrr/+ev32t79V9+7dNXnyZAUFBSkyMlI5OTnq3r27Hn30UR04cECffPJJs/fdqVMnBQUFKTAwUC6XSy6XSwEBAaetf+yxxzRkyBD16tVLixYt0r59+7R8+fLv9Vy///3vNWvWLI0aNUrx8fEaNWqUfv3rX2v+/Pk+dXl5eVZNbGxss48JQMviHB0AF1Tv3r2tr/38/BQREaFevXpZ26KjoyVJ1dXVF7yXlJQU6+vw8HAlJCRo27ZtZ33c/v37VVFRobFjxyonJ8fafuzYMTmdTp/aPn36tFzDAM4bQQfABXXyybgOh8Nn24nzb44fP6527do1+VTj7/vW0rk63fk/33X8+HFJ3759lZyc7DPm5+fnsx4cHNxyzQE4bwQdAJeMzp076/Dhw6qrq7MCw9nuhRMQEKDGxsbvtf+SkhJ17dpVklRTU6MvvvhC11577VkfFx0drR/84Af66quv9POf//x7PReASwNBB8AlIzk5WR07dtSUKVM0YcIEbd68WQsXLjzjY6688kq988472r59uyIiIpq8lfRdTzzxhCIiIhQdHa1HHnlEkZGRTe7BczoFBQXKzc1VaGiohg0bJq/Xqw8//FA1NTWaOHFiM44SwMXEycgALhnh4eFasmSJ3n77bfXq1UuvvvqqCgoKzviYnJwcJSQkqE+fPurcubM++OCD09bOmDFDDz74oJKSklRZWak333zzjCcvf9cvf/lL/d///Z8WLlyoXr16acCAAVq4cKHi4+Obc4gALjKHOfkNcQCwmXXr1mngwIGqqalpcp8eAPbGjA4AALAtgg4AALAt3roCAAC2xYwOAACwLYIOAACwLYIOAACwLYIOAACwLYIOAACwLYIOAACwLYIOAACwLYIOAACwrf8PMHfUnIgrE/MAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "df.plot(x=\"multiplier\", y=\"count\", kind=\"bar\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5b977bc8-02f7-4155-8196-faf5c3507de6",
   "metadata": {},
   "source": [
    "### 一言以蔽之\n",
    "\n",
    "spark sql使用更具体与语义化的算子，降低了编程的表达能力，但是利用算子具体的语义化信息，spark sql 可以优化我们的执行计划，提高执行的效率\n",
    "\n",
    "spark-sql的底层还是spark-core，牺牲了rdd的灵活性换取更高的运行效率"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
